/**
 * 
 */
package co.fitstart.payment.service.impl;

import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.BusinessException;
import com.demo2do.core.persistence.GenericJdbcSupport;

import co.fitstart.payment.dao.RefundRecordDaoSupport;
import co.fitstart.payment.dao.TransactionRecordDaoSupport;
import co.fitstart.payment.entity.request.RefundRecord;
import co.fitstart.payment.entity.transaction.TransactionRecord;
import co.fitstart.payment.entity.transaction.TransactionStatus;
import co.fitstart.payment.service.RefundRecordService;

/**
 * @author lute
 *
 */
@Service("refundRecordService")
public class RefundRecordServiceImpl implements RefundRecordService {

    @Autowired
    private GenericJdbcSupport genericJdbcSupport;
    
    @Autowired
    private RefundRecordDaoSupport refundRecordDaoSupport;
    
    @Autowired
    private TransactionRecordDaoSupport transactionRecordDaoSupport;
    
    /* (non-Javadoc)
     * @see co.fitstart.payment.service.RefundRecordService#create(co.fitstart.payment.entity.request.RefundRecord)
     */
    public void create(RefundRecord refundRecord) {
        String sentence = "INSERT INTO refund_record (app_id, channel_id, transaction_record_id, refund_no, refund_id, order_no, total_amount, refund_amount, is_batch, batch_data, notify_url, refund_time, is_finished, is_disabled) VALUES (:appId, :channelId, :transactionRecordId, :refundNo, :refundId, :orderNo, :totalAmount, :refundAmount, :batch, :batchData, :notifyUrl, :refundTime, :finished, :disabled)";
        genericJdbcSupport.executeSQL(sentence, refundRecord);
    }
    
    /* (non-Javadoc)
     * @see co.fitstart.payment.service.RefundRecordService#getFinishedRefundRecords(co.fitstart.payment.entity.transaction.TransactionRecord)
     */
    public List<RefundRecord> getFinishedRefundRecords(TransactionRecord transactionRecord) {
        return refundRecordDaoSupport.getFinishedRefundRecord(transactionRecord);
    }

    /* (non-Javadoc)
     * @see co.fitstart.payment.service.RefundRecordService#refund(java.lang.String, java.lang.String)
     */
    public void refund(String refundNo, String refundId) {
        
        // Get refund record from refund number
        RefundRecord refundRecord = refundRecordDaoSupport.getRefundRecord(refundNo);
        int refundAmount = refundRecord.getRefundAmount();
        
        // Get transaction record by transaction record id
        TransactionRecord transactionRecord = transactionRecordDaoSupport.loadTransactionRecord(refundRecord.getTransactionRecordId());
        
        // Get all finished refund records and calculate refunded amount
        List<RefundRecord> refundRecords = refundRecordDaoSupport.getFinishedRefundRecord(transactionRecord);
        int refundedAmount = 0;
        if (CollectionUtils.isNotEmpty(refundRecords)) {
            for (RefundRecord record : refundRecords) {
                refundedAmount += record.getRefundAmount();
            }
        }
        
        // Update transaction record status according to refunded amount
        if (refundedAmount + refundAmount < transactionRecord.getAmount()) {
            transactionRecordDaoSupport.changeTransactionRecordStatus(transactionRecord, TransactionStatus.PARTIAL_REFUNDED);
        } else if (refundedAmount + refundAmount == transactionRecord.getAmount()) {
            transactionRecordDaoSupport.changeTransactionRecordStatus(transactionRecord, TransactionStatus.REFUNDED);
        } else {
            throw new BusinessException("Refund amount is more than total amount!");
        }
        
        // Update refund record
        String sentence = "UPDATE refund_record SET refund_id = :refundId, is_finished = :finished WHERE id = :id";
        genericJdbcSupport.executeSQL(sentence, refundRecord.refund(refundId));
    }

}
